package master.common.utils;

import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 */
public class UtilDateConverter{
	private static final Pattern UTILDATEPATTERN = Pattern.compile("^\\s*((((\\d{4})|(\\d{2}))[-./－])?(\\d{1,2})[-./－](\\d{1,2}))?\\s*(上午|下午)?\\s*(([0-2]?\\d{1})([\\:：](\\d{1,2})([:：](\\d{1,2}))?)?)?\\s*", Pattern.CASE_INSENSITIVE);
	private static final Pattern SPECIALPATTERN = Pattern.compile("^\\s*((\\d{4})|(\\d{2}))([-－./年](\\d{1,2})([-－./月](\\d{1,2})日?)?)?", Pattern.CASE_INSENSITIVE);
	private static Map<Locale, DateFormat> dfMap = new HashMap<Locale, DateFormat>();
	private static Map<Locale, DateFormat> dtfMap = new HashMap<Locale, DateFormat>();
	
	@SuppressWarnings("unchecked")
	public static <T> T convert(Class<T> type, Object value) {
		if (value == null) {
			throw new IllegalArgumentException("待转换值为null");
		}
		if (type.equals(java.sql.Date.class)) {
			if (value instanceof Date) {
				return (T)value;
			} else {
				try {
					return (T)Date.valueOf(String.valueOf(value));
				} catch (Exception e) {
					throw new IllegalArgumentException(e);
				}
			}
		} else if (type.equals(java.util.Date.class)) {
			if (value instanceof java.util.Date) {
				return (T)value;
			} else {
				try {
					return (T)parse(String.valueOf(value));
				} catch (Exception e) {
					throw new IllegalArgumentException(e);
				}
			}
		}
		else{
			throw new IllegalArgumentException("不能识别的类型");
		}
	}
	
	public static java.util.Date parse(String dateStr){
		Matcher m = UTILDATEPATTERN.matcher(dateStr);
		String[] group = new String[15];
		if (m.find()) {
			Arrays.fill(group, null);
			
			Calendar c = Calendar.getInstance();
			c.set(c.get(Calendar.YEAR), 0, 1);
			int gcount = m.groupCount();
			for (int i = 0; i <= gcount; i++) {
				group[i] = m.group(i);				
			}
			int year = group[3]==null?c.get(Calendar.YEAR):Integer.parseInt(group[3]);
			if (year<100) {
				year += year>30?1900:2000;
			}
			int month = group[6]==null?c.get(Calendar.MONTH):Integer.parseInt(group[6])-1;
			int date = group[7]==null?c.get(Calendar.DATE):Integer.parseInt(group[7]);
			int hour = group[10]==null?0:Integer.parseInt(group[10]);
			if ("下午".equals(group[8])) {
				hour += 12;
			}
			int min = group[12]==null?0:Integer.parseInt(group[12]);
			int sec = group[14]==null?0:Integer.parseInt(group[14]);
			
			c.set(year, month, date, hour, min, sec);
			c.set(Calendar.MILLISECOND, 0);
			return new java.util.Date(c.getTimeInMillis());
		} else {
			return parseBySpecialFmt(dateStr);
		}
	}
	
	private static java.util.Date parseBySpecialFmt(String dateStr){
		Matcher m = SPECIALPATTERN.matcher(dateStr);
		String[] group = new String[8];
		if (m.find()) {
			Arrays.fill(group, null);			
			Calendar c = Calendar.getInstance();
			c.set(c.get(Calendar.YEAR), 0, 1);
			int gcount = m.groupCount();
			for (int i = 0; i <= gcount; i++) {
				group[i] = m.group(i);				
			}
			int year = group[1]==null?c.get(Calendar.YEAR):Integer.parseInt(group[1]);
			if (year<100) {
				year += year>30?1900:2000;
			}
			int month = group[5]==null?c.get(Calendar.MONTH):Integer.parseInt(group[5])-1;
			int date = group[7]==null?c.get(Calendar.DATE):Integer.parseInt(group[7]);
			c.set(year, month, date);
			return new java.util.Date(c.getTimeInMillis());
		}else{
			throw new IllegalArgumentException("不能识别的字符串格式！");
		}
	}
	
	public static String toDateString(java.util.Date date){
		if(date == null){
			return "";
		}
		DateFormat df = getDateFormat(Locale.getDefault());
		synchronized (df) {
			return df.format(date);
		}
	}
	
	public static String toDateTimeString(java.util.Date date){
		if(date == null){
			return "";
		}
		DateFormat df = getDateTimeFormat(Locale.getDefault());
		synchronized (df) {
			return df.format(date);
		}
	}
	
	private static synchronized DateFormat getDateFormat(Locale locale){
		DateFormat df = dfMap.get(locale);
		if (df == null) {
			df = new SimpleDateFormat("yyyy-MM-dd", locale);
			dfMap.put(locale, df);
		}
		return df;
	}
	
	private static synchronized DateFormat getDateTimeFormat(Locale locale){
		DateFormat df = dtfMap.get(locale);
		if (df == null) {
			df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", locale);
			dtfMap.put(locale, df);
		}
		return df;
	}
}
